Skip to content

Commit fca9a74

Browse files
committed
Add tests for Stage 3 Decorator Metadata
1 parent 99ac701 commit fca9a74

22 files changed

+782
-0
lines changed

features.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ regexp-v-flag
7777
# https://github.com/tc39/proposal-decorators
7878
decorators
7979

80+
# Decorator Metadata
81+
# https://github.com/tc39/proposal-decorator-metadata
82+
decorator-metadata
83+
8084
# Duplicate named capturing groups
8185
# https://github.com/tc39/proposal-duplicate-named-capturing-groups
8286
regexp-duplicate-named-groups
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
esid: sec-function.prototype-@@metadata
5+
description: Function.prototype[Symbol.metadata] property descriptor
6+
info: |
7+
The initial value of the @@metadata property is null.
8+
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
9+
false, [[Configurable]]: false }.
10+
includes: [propertyHelper.js]
11+
features: [decorator-metadata]
12+
---*/
13+
14+
verifyProperty(Function.prototype, Symbol.metadata, {
15+
value: null,
16+
writable: false,
17+
enumerable: false,
18+
configurable: false
19+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
esid: sec-symbol.metadata
5+
description: Value shared by all realms
6+
info: |
7+
Unless otherwise specified, well-known symbols values are shared by all
8+
realms.
9+
features: [cross-realm, decorator-metadata]
10+
---*/
11+
12+
var OSymbol = $262.createRealm().global.Symbol;
13+
14+
assert.sameValue(Symbol.metadata, OSymbol.metadata);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
esid: sec-symbol.metadata
5+
description: >
6+
`Symbol.metadata` property descriptor
7+
info: |
8+
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
9+
false, [[Configurable]]: false }.
10+
includes: [propertyHelper.js]
11+
features: [decorator-metadata]
12+
---*/
13+
14+
assert.sameValue(typeof Symbol.metadata, 'symbol');
15+
verifyNotEnumerable(Symbol, 'metadata');
16+
verifyNotWritable(Symbol, 'metadata');
17+
verifyNotConfigurable(Symbol, 'metadata');
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
esid: sec-createdecoratorcontextobject
5+
description: >
6+
Property descriptor for metadata property of decorator context object.
7+
info: |
8+
CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] )
9+
[...]
10+
13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata).
11+
14. Return contextObj.
12+
includes: [propertyHelper.js]
13+
features: [decorators, decorator-metadata]
14+
---*/
15+
16+
var contextObj;
17+
function dec(_, context) {
18+
contextObj = context;
19+
}
20+
21+
void @dec class C {};
22+
assert.sameValue(typeof contextObj.metadata, "object");
23+
verifyNotEnumerable(contextObj, "metadata");
24+
verifyWritable(contextObj, "metadata");
25+
verifyConfigurable(contextObj, "metadata");
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
/*---
4+
esid: sec-createdecoratorcontextobject
5+
description: >
6+
Property descriptor for metadata property of decorator context object.
7+
info: |
8+
CreateDecoratorContextObject ( kind, name, initializers, decorationState, metadataObj [ , isStatic ] )
9+
[...]
10+
13. Perform ! CreateDataPropertyOrThrow(contextObj, "metadata", metadata).
11+
14. Return contextObj.
12+
includes: [deepEqual.js]
13+
features: [decorators, decorator-metadata]
14+
---*/
15+
16+
var kinds = {
17+
"class": false,
18+
"public method": false,
19+
"public getter": false,
20+
"public setter": false,
21+
"public field": false,
22+
"public accessor": false,
23+
"private method": false,
24+
"private getter": false,
25+
"private setter": false,
26+
"private field": false,
27+
"private accessor": false,
28+
};
29+
function dec(_, context) {
30+
const key = `${context.private ? "private" : "public"} ${context.kind}`;
31+
kinds[key] = typeof context.metadata === "object";
32+
}
33+
34+
void @dec class C {
35+
@dec method() {}
36+
@dec get getter() {}
37+
@dec set setter(x) {}
38+
@dec field;
39+
@dec accessor accessor;
40+
@dec #method() {}
41+
@dec get #getter() {}
42+
@dec set #setter(x) {}
43+
@dec #field;
44+
@dec accessor #accessor;
45+
};
46+
47+
assert.deepEqual(kinds, {
48+
"class": true,
49+
"public method": true,
50+
"public getter": true,
51+
"public setter": true,
52+
"public field": true,
53+
"public accessor": true,
54+
"private method": true,
55+
"private getter": true,
56+
"private setter": true,
57+
"private field": true,
58+
"private accessor": true,
59+
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-runtime-semantics-classdefinitionevaluation
6+
description: >
7+
Metadata is only attached when a class or class element is decorated.
8+
info: |
9+
ClassTail : ClassHeritage_opt { ClassBody_opt }
10+
21. Let hasDecorators be false.
11+
22. If decorators is not empty, set hasDecorators to true.
12+
[...]
13+
25. For each ClassElement e of elements, do
14+
[...]
15+
e. If element is a ClassElementDefinition Record, then
16+
i. If e.[[Decorators]] is not empty, set hasDecorators to true.
17+
[...]
18+
[...]
19+
29. Let metadataObj be empty.
20+
30. If hasDecorators is true, then
21+
a. If ClassHeritage is present, [...]
22+
b. Else, let metadataParent be null.
23+
c. Set metadataObj to OrdinaryObjectCreate(metadataParent).
24+
[...]
25+
41. If metadataObj is not empty, then
26+
a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })).
27+
1. If _setMetadataResult_ is an abrupt completion, then
28+
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
29+
1. Return ? _setMetadataResult_.
30+
[...]
31+
features: [decorators, decorator-metadata]
32+
---*/
33+
34+
function dec() {}
35+
36+
let C1 = @dec class C1 {};
37+
assert.sameValue(typeof C1[Symbol.metadata], "object");
38+
39+
let C2 = class C2 { @dec method() {} };
40+
assert.sameValue(typeof C2[Symbol.metadata], "object");
41+
42+
let C3 = class C3 {};
43+
assert.sameValue(typeof C3[Symbol.metadata], "undefined");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-runtime-semantics-classdefinitionevaluation
6+
description: >
7+
Metadata on a derived class inherits from the metadata of the declared super class.
8+
info: |
9+
ClassTail : ClassHeritage_opt { ClassBody_opt }
10+
21. Let hasDecorators be false.
11+
22. If decorators is not empty, set hasDecorators to true.
12+
[...]
13+
25. For each ClassElement e of elements, do
14+
[...]
15+
e. If element is a ClassElementDefinition Record, then
16+
i. If e.[[Decorators]] is not empty, set hasDecorators to true.
17+
[...]
18+
[...]
19+
29. Let metadataObj be empty.
20+
30. If hasDecorators is true, then
21+
a. If ClassHeritage is present, [...]
22+
b. Else, let metadataParent be null.
23+
c. Set metadataObj to OrdinaryObjectCreate(metadataParent).
24+
[...]
25+
41. If metadataObj is not empty, then
26+
a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })).
27+
1. If _setMetadataResult_ is an abrupt completion, then
28+
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
29+
1. Return ? _setMetadataResult_.
30+
[...]
31+
features: [decorators, decorator-metadata]
32+
---*/
33+
34+
function dec() {}
35+
36+
class UndecoratedBase {}
37+
38+
let Base = @dec class Base {};
39+
const baseMetadata = Base[Symbol.metadata];
40+
41+
let Derived = @dec class Derived extends Base { };
42+
Object.setPrototypeOf(Derived, UndecoratedBase);
43+
44+
const derivedMetadata = Derived[Symbol.metadata];
45+
assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-runtime-semantics-classdefinitionevaluation
6+
description: >
7+
Metadata on a derived class inherits from the metadata of the declared super class.
8+
info: |
9+
ClassTail : ClassHeritage_opt { ClassBody_opt }
10+
21. Let hasDecorators be false.
11+
22. If decorators is not empty, set hasDecorators to true.
12+
[...]
13+
25. For each ClassElement e of elements, do
14+
[...]
15+
e. If element is a ClassElementDefinition Record, then
16+
i. If e.[[Decorators]] is not empty, set hasDecorators to true.
17+
[...]
18+
[...]
19+
29. Let metadataObj be empty.
20+
30. If hasDecorators is true, then
21+
a. If ClassHeritage is present, [...]
22+
b. Else, let metadataParent be null.
23+
c. Set metadataObj to OrdinaryObjectCreate(metadataParent).
24+
[...]
25+
41. If metadataObj is not empty, then
26+
a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })).
27+
1. If _setMetadataResult_ is an abrupt completion, then
28+
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
29+
1. Return ? _setMetadataResult_.
30+
[...]
31+
features: [decorators, decorator-metadata]
32+
---*/
33+
34+
function dec() {}
35+
36+
class UndecoratedBase {}
37+
38+
let Base = @dec class Base {};
39+
const baseMetadata = Base[Symbol.metadata];
40+
41+
let Derived = @dec class Derived extends Base { };
42+
Base[Symbol.metadata] = {};
43+
44+
const derivedMetadata = Derived[Symbol.metadata];
45+
assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-runtime-semantics-classdefinitionevaluation
6+
description: >
7+
Metadata is only attached when a class or class element is decorated.
8+
info: |
9+
ClassTail : ClassHeritage_opt { ClassBody_opt }
10+
21. Let hasDecorators be false.
11+
22. If decorators is not empty, set hasDecorators to true.
12+
[...]
13+
25. For each ClassElement e of elements, do
14+
[...]
15+
e. If element is a ClassElementDefinition Record, then
16+
i. If e.[[Decorators]] is not empty, set hasDecorators to true.
17+
[...]
18+
[...]
19+
29. Let metadataObj be empty.
20+
30. If hasDecorators is true, then
21+
a. If ClassHeritage is present, [...]
22+
b. Else, let metadataParent be null.
23+
c. Set metadataObj to OrdinaryObjectCreate(metadataParent).
24+
[...]
25+
41. If metadataObj is not empty, then
26+
a. Let setMetadataResult be Completion(DefinePropertyOrThrow(F, @@metadata, PropertyDescriptor { [[Value]]: metadataObj, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })).
27+
1. If _setMetadataResult_ is an abrupt completion, then
28+
1. Set the running execution context's PrivateEnvironment to _outerPrivateEnvironment_.
29+
1. Return ? _setMetadataResult_.
30+
[...]
31+
features: [decorators, decorator-metadata]
32+
---*/
33+
34+
function dec() {}
35+
36+
let Base = @dec class Base {};
37+
const baseMetadata = Base[Symbol.metadata];
38+
assert.sameValue(Object.getPrototypeOf(baseMetadata), null);
39+
40+
let Derived = @dec class Derived extends Base { };
41+
const derivedMetadata = Derived[Symbol.metadata];
42+
assert.sameValue(Object.getPrototypeOf(derivedMetadata), baseMetadata);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (C) 2023 Ron Buckton. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-runtime-semantics-classdefinitionevaluation
6+
description: >
7+
The metadata object is a regular, extensible JS object.
8+
info: |
9+
ClassTail : ClassHeritage_opt { ClassBody_opt }
10+
21. Let hasDecorators be false.
11+
22. If decorators is not empty, set hasDecorators to true.
12+
[...]
13+
25. For each ClassElement e of elements, do
14+
[...]
15+
e. If element is a ClassElementDefinition Record, then
16+
i. If e.[[Decorators]] is not empty, set hasDecorators to true.
17+
[...]
18+
[...]
19+
29. Let metadataObj be empty.
20+
30. If hasDecorators is true, then
21+
a. If ClassHeritage is present, [...]
22+
b. Else, let metadataParent be null.
23+
c. Set metadataObj to OrdinaryObjectCreate(metadataParent).
24+
[...]
25+
features: [decorators, decorator-metadata]
26+
---*/
27+
28+
function dec() {}
29+
30+
let C = @dec class C {};
31+
const metadata = C[Symbol.metadata];
32+
assert(Object.isExtensible(metadata));

0 commit comments

Comments
 (0)